<!doctype html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <!-- <meta http-equiv="refresh" content="1" > -->

    <title>操作当前地图</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }

        body {
            background: rgba(3, 3, 3, 0.199);
        }

        .box {
            background-color: darkseagreen;
            height: 80%;
            width: 100%;
        }

        .canvas_css {
            background-color: darkseagreen;
            float: left;
            /* height: 80%;
            width: 100%; */
            margin: auto;
        }

        .bt_css {
            background-color: rgb(245, 245, 220);
            float: right;
            /* height: 50%;
            width: 50%; */
            margin: auto;
        }

        .ul {
            display: flex;
            align-items: center;
            list-style: none;
            margin: 10px auto;
            float: left;
        }

        .ul > li {
            margin-right: 10px;
        }

        canvas {
            position: absolute;
            top: 0;
            left: 0;
        }

        /* 多层画布 */
        .backgrounds {
            z-index: 0;
            -webkit-filter: blur(6px);
            filter: blur(6px);
            background-image: -webkit-radial-gradient(#4682b4, #191970);
            background-image: radial-gradient(#4682b4, #191970);
        }

        .back {
            z-index: 1;
            -webkit-filter: blur(6px);
            filter: blur(6px);
            background-image: -webkit-radial-gradient(#4682b4, #191970);
            background-image: radial-gradient(#4682b4, #191970);
        }

        .mid {
            z-index: 2;
            -webkit-filter: blur(3px);
            filter: blur(3px);
            mix-blend-mode: lighten;
            background: rgba(255, 255, 255, 0);
        }

        .front {
            z-index: 3;
            -webkit-filter: blur(1px);
            filter: blur(1px);
            mix-blend-mode: luminosity;
        }
    </style>
</head>

<body>
<div class="box" id='content'>

    <div class="bt_css" id='content1'>
        <ul class="ul">
            <li>
                <button onclick="on_normal()" id="normal_mode"> 普通模式</button>

            </li>
            <li>
                <button onclick="on_reclocal()" id="relocal_mode"> 重定位模式</button>
            </li>
        </ul>
    </div>
    <canvas class="canvas_css" id='canvas' width=1900 height=900 style="border: 1px solid">
        您的浏览器版本过低，请更新浏览器
    </canvas>
    <canvas id="backgrounds" width=1900 height=800></canvas>
    <canvas id="back" width=1900 height=800></canvas>
    <canvas id="mid" width=1900 height=800></canvas>
    <canvas id="front" width=1900 height=800></canvas>
</div>


<script type="text/javascript">

    var g_offset = {
        x: 80,
        y: 80
    }

    var g_size = {
        x: 10,
        y: 10
    }

    var g_robot_position = {
        x: 0,
        y: 0,
        theta: 0
    }

    var g_map_data = "";
    var g_get_slam_data = null;
    var g_slam_flag = false;
    var g_timer_id = null;
    var g_get_slam_map_url = "/get_map_data?type=get_slam_data";
    var g_get_pointcloud_url = "/get_map_data?type=get_pointCloud";
    var g_get_robot_state_url = "/get_map_data?type=get_robotState";
    var g_get_using_map_url = "/get_map_data?type=get_using_map";
    var g_countryList = []
    let g_pointcloud_x = [];
    let g_pointcloud_y = [];
    const g_img = new Image();
    var g_mode_flag = "normal";
    var g_current_scale = 1;

    // 初始化画布
    var gg_background_canvas = document.getElementById("backgrounds");
    var gg_map_canvas = document.getElementById("back");
    var gg_robot_canvas = document.getElementById("mid");
    var gg_pcl_canvas = document.getElementById("front");

    g_background_canvas = gg_background_canvas.getContext('2d'); // 背景画布
    g_map_canvas = gg_map_canvas.getContext('2d'); // 地图画布
    g_robot_canvas = gg_robot_canvas.getContext('2d'); // 机器人画布
    g_pcl_canvas = gg_pcl_canvas.getContext('2d'); // 点云画布

    myresize();

    // 通用get请求
    function get_map_data(theUrl) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET", theUrl, false); // false for synchronous request
        xmlHttp.send(null);
        // json_data = JSON.parse(xmlHttp.responseText);
        return JSON.parse(xmlHttp.responseText);
    }

    //获取窗口宽度
    function w() {
        if (window.innerWidth) {  //兼容DOM
            return window.innerWidth;
        }
        if ((document.body) && (document.body.clientWidth)) {  //兼容IE
            return document.body.clientWidth;
        }
    }

    //获取窗口高度
    function h() {
        if (window.innerHeight) {  //兼容DOM
            return window.innerHeight;
        }
        if ((document.body) && (document.body.clientHeight)) { //兼容IE
            return document.body.clientHeight;
        }
    }

    // 绘制机器人坐标及实时地图、点云
    function draw_slam_map() {

        // 请求slam实时数据

        // g_get_slam_data = JSON.parse( get_map_data(g_get_slam_map_url) );
        g_get_slam_data = get_map_data(g_get_using_map_url);
        // 清除背景
        clear("background");
        if (g_get_slam_data.code == 0) {
            g_slam_flag = true;
            draw("background");
        } else {
            g_slam_flag = false;
            draw("no_map");
            return false;
        }
        // console.info(g_get_slam_data);


        // 给地图全局变量
        g_map_data = g_get_slam_data.data.AGVMap.mapData
        clear("map");
        draw("map");

        // 机器人坐标
        g_robot_position.x = (-g_get_slam_data.data.AGVMap.originX + g_get_slam_data.data.robotPose.x) / g_get_slam_data.data.AGVMap.resolution
        g_robot_position.y = (g_get_slam_data.data.AGVMap.physicsHeight + g_get_slam_data.data.AGVMap.originY - g_get_slam_data.data.robotPose.y) / g_get_slam_data.data.AGVMap.resolution
        g_robot_position.theta = g_get_slam_data.data.robotPose.theta

        if (g_get_slam_data.data.robotPose.x != 0 && g_get_slam_data.data.robotPose.y != 0) {
            clear("robot");
            draw("robot");
        }

        // 绘制点云地图
        // 绘制点云
        // 请求pointcloud实时数据
        var point_cloud_json = get_map_data(g_get_pointcloud_url);
        g_countryList = point_cloud_json.data.pointCloud;
        if (g_countryList.length > 0) {
            g_pointcloud_x = []
            g_pointcloud_y = []
            for (var i = 0; i < g_countryList.length; i++) {
                var pix_x = (-g_get_slam_data.data.AGVMap.originX + g_countryList[i]["x"]) / g_get_slam_data.data.AGVMap.resolution;
                var pix_y = (g_get_slam_data.data.AGVMap.physicsHeight + g_get_slam_data.data.AGVMap.originY - g_countryList[i]["y"]) / g_get_slam_data.data.AGVMap.resolution;
                // 填充全局容器
                g_pointcloud_x.push(pix_x);
                g_pointcloud_y.push(pix_y);
            }

            // 清除并重绘
            clear("pointcloud");
            draw("pointcloud");
        }
        // 加载地图->触发回调事件
        g_img.src = g_get_slam_data.data.AGVMap.mapData

    }

    //ctx指定画布,stepX是线与线x间距 stepY是线与线y间距 color是线的颜色 lineWidth是线的宽度
    function drawGrid(ctx, stepX, stepY, color, lineWidth) {
        // // 设置绘制颜色
        ctx.strokeStyle = color;
        // 创建垂直格网线路径
        for (let i = stepX; i < canvas.width; i += stepX) {
            // 设置绘制线段的宽度
            ctx.lineWidth = lineWidth;
            //开启路径
            ctx.beginPath()

            //笔触的位置-moveTo经常是画一些不连续的线
            ctx.moveTo(i, 0);
            //绘制一条从当前位置到指定x以及y位置的直线。
            ctx.lineTo(i, canvas.height);
            ctx.stroke()
        }
        // 创建水平格网线路径
        for (let j = stepY; j < canvas.height; j += stepY) {
            // 设置绘制线段的宽度
            ctx.lineWidth = lineWidth;
            //开启路径
            ctx.beginPath()
            ctx.moveTo(0, j);
            ctx.lineTo(canvas.width, j);
            ctx.stroke()
        }
    }

    function draw(type) {
        if (type == "map") {
            g_map_canvas.drawImage(g_img, g_offset.x, g_offset.y);
        }
        if (type == "robot") {
            // 点位置
            g_robot_canvas.save();
            g_robot_canvas.beginPath();
            // 旋转到正确角度
            //g_robot_canvas.translate(g_size.x, g_size.y);
            //g_robot_canvas.rotate(g_robot_position.theta);
            //g_robot_canvas.translate(-g_size.x, -g_size.y);

            g_robot_canvas.rect(g_offset.x + g_robot_position.x, g_offset.y + g_robot_position.y, 10, 10);
            g_robot_canvas.strokeStyle = 'blue';
            g_robot_canvas.lineWidth = 0;
            g_robot_canvas.fillStyle = 'blue';
            g_robot_canvas.fill();
            g_robot_canvas.stroke();
            g_robot_canvas.closePath();

        }

        if (type == "pointcloud") {

            g_pcl_canvas.save();
            g_pcl_canvas.beginPath();
            for (var i = 0; i < g_pointcloud_x.length; i++) {
                g_pcl_canvas.rect(g_offset.x + g_pointcloud_x[i], g_offset.y + g_pointcloud_y[i], 1, 1);
                g_pcl_canvas.strokeStyle = 'red';
                g_pcl_canvas.lineWidth = 0;
                g_pcl_canvas.fillStyle = 'red';
                g_pcl_canvas.fill();
                g_pcl_canvas.stroke();

            }
            g_pcl_canvas.closePath();
        }

        if (type == "background") {
            //调用封装好的表格工具
            drawGrid(g_background_canvas, 20, 20, '#ffffff', 0.5);
        }


        if (type == "no_slam") {
            clear("map");
            clear("robot");
            clear("pointcloud");
            g_background_canvas.font = "50px serif";
            g_background_canvas.fillStyle = "#ff0000";
            g_background_canvas.fillText("slam模式未就绪！", 0, 50);
        }


        if (type == "no_map") {
            clear("map");
            clear("robot");
            clear("pointcloud");
            g_background_canvas.font = "50px serif";
            g_background_canvas.fillStyle = "#ff0000";
            g_background_canvas.fillText("定位模式未就绪或不存在地图！", 0, 50);
        }

    }

    function clear_all() {
        clear("background");
        clear("map");
        clear("robot");
        clear("pointcloud");
    }

    function draw_all() {
        draw("background");
        if (g_slam_flag) {
            draw("map");
            draw("robot");
            draw("pointcloud");
        }
    }

    // 清除画布
    function clear(type) {
        if (type == "map") {
            g_map_canvas.beginPath();
            g_map_canvas.clearRect(0, 0, canvas.width, canvas.height);
            g_map_canvas.stroke();
        }
        if (type == "robot") {
            g_robot_canvas.beginPath();
            g_robot_canvas.clearRect(0, 0, canvas.width, canvas.height);
            g_robot_canvas.stroke();
        }

        if (type == "pointcloud") {
            g_pcl_canvas.beginPath();
            g_pcl_canvas.clearRect(0, 0, canvas.width, canvas.height);
            g_pcl_canvas.stroke();
        }

        if (type == "background") {
            g_background_canvas.beginPath();
            g_background_canvas.clearRect(0, 0, canvas.width, canvas.height);
            g_background_canvas.stroke();
        }

    }

    function myresize(e) {
        canvas.setAttribute("width", w() * 0.7)
        canvas.setAttribute("height", h() * 1.0)
        gg_map_canvas.setAttribute("width", w() * 0.7)
        gg_map_canvas.setAttribute("height", h() * 1.0)
        gg_robot_canvas.setAttribute("width", w() * 0.7)
        gg_robot_canvas.setAttribute("height", h() * 1.0)
        gg_pcl_canvas.setAttribute("width", w() * 0.7)
        gg_pcl_canvas.setAttribute("height", h() * 1.0)
        gg_background_canvas.setAttribute("width", w() * 0.7)
        gg_background_canvas.setAttribute("height", h() * 1.0)

        // console.log("窗口尺寸改变了！")
        // console.log(w())
        // console.log(h())
    }

    function re_draw_all() {
        clear_all();
        draw_all();
    }

    // 监听各种事件
    function listen_event() {
        // 记录鼠标按下时，画布本身的偏移量
        var click_offset = {
            x: 0,
            y: 0
        }

        // 记录鼠标按下的坐标
        var click_position = {
            x: 0,
            y: 0
        }

        // 记录鼠标松开的坐标
        var clickout_position = {
            x: 0,
            y: 0
        }
        var move_flag = false;

        function mymousemove(e) {
            if (!move_flag) return;
            if (g_mode_flag == "normal") {
                // console.log("move")
                // console.log(e.offsetX)
                // console.log(e.offsetY)
                g_offset.x = click_offset.x + e.offsetX - click_position.x;
                g_offset.y = click_offset.y + e.offsetY - click_position.y;
                // console.log(g_offset)

                setTimeout(re_draw_all, 50) // 防止过高刷新率造成内存不够或浏览器响应不过来
            }


            if (g_mode_flag == "reclocal") {
                // 像素到地图的坐标换算后，调用重定位[todo]动画效果
                // clickout_position.x = e.offsetX;
                // clickout_position.y = e.offsetY;
                // var x = click_position.x;
                // var y = click_position.y;
                // var theta = -Math.atan2((clickout_position.y-click_position.y), (clickout_position.x-click_position.y)) // Y轴相反
                // set_relocal(x, y, theta);

            }
        }

        function myclick() {
            // console.log("我被点了一下！") // 触发条件为点击并松开
        }

        function mydblclick() {
            // console.log("我被点了两下！")
        }

        function mymouseEnter() {
            // console.log("我的鼠标移进来了！")
        }

        function mymouseOut(e) {
            move_flag = false;

            // console.log("我的鼠标移出去了！")
        }

        function mymousesDown(e) {
            move_flag = true;
            if (g_mode_flag == "normal") {
                click_position.x = e.offsetX
                click_position.y = e.offsetY

                // 保证任何时刻点击后移动的顺畅
                click_offset.x = g_offset.x;
                click_offset.y = g_offset.y;
            }


            if (g_mode_flag == "reclocal") {
                click_position.x = e.offsetX
                click_position.y = e.offsetY
            }
            // console.log(click_position);
            // console.log("我的鼠标点下去了！")
        }

        function mymouseUp(e) {
            move_flag = false;
            if (g_mode_flag == "normal") {
                click_position.x = 0
                click_position.y = 0
            }

            if (g_mode_flag == "reclocal") {
                clickout_position.x = e.offsetX
                clickout_position.y = e.offsetY
                // 像素到地图的坐标换算后，调用重定位
                var x = click_position.x;
                var y = click_position.y;
                var theta = -Math.atan2((clickout_position.y - click_position.y), (clickout_position.x - click_position.x)) // Y轴相反
                set_relocal(x, y, theta);
                // 初始化变量，下次使用
                click_position.x = 0
                click_position.y = 0
                clickout_position.x = 0
                clickout_position.y = 0
                g_mode_flag = "normal" // 重定位1次即回到普通模式
            }
            // console.log("我的鼠标松开了！")
        }

        function mywheel(e) {
            if (g_mode_flag == "normal") {
                // console.log(e.deltaY)
                var scale = 1.0;
                // 放大
                if (e.deltaY < 0) {
                    scale = 1.1;
                }
                // 缩小
                else {
                    scale = 0.9;
                }
                g_map_canvas.scale(scale, scale);
                g_pcl_canvas.scale(scale, scale);
                g_robot_canvas.scale(scale, scale);
                g_current_scale *= scale
                re_draw_all();
            }

            if (g_mode_flag == "reclocal") {

            }

        }

        // 添加事件
        gg_pcl_canvas.addEventListener('mousemove', mymousemove, true);
        gg_pcl_canvas.addEventListener('click', myclick, true);
        gg_pcl_canvas.addEventListener('dblclick', mydblclick, true);
        gg_pcl_canvas.addEventListener('mouseenter', mymouseEnter, true);
        gg_pcl_canvas.addEventListener('mouseout', mymouseOut, true);
        gg_pcl_canvas.addEventListener('mousedown', mymousesDown, true);
        gg_pcl_canvas.addEventListener('mouseup', mymouseUp, true);
        gg_pcl_canvas.addEventListener('wheel', mywheel, true);
        window.addEventListener('resize', myresize, true);
    }

    // 触发切换普通模式标志
    function on_normal() {
        g_mode_flag = "normal";
    }

    // 触发切换重定位模式标志
    function on_reclocal() {
        g_mode_flag = "reclocal";
    }

    // 设置重定位坐标
    function set_relocal(x, y, theta) {
        // 反计算时，考虑当前的缩放比例
        temp_x = (x / g_current_scale - g_offset.x) * g_get_slam_data.data.AGVMap.resolution + g_get_slam_data.data.AGVMap.originX;
        temp_y = -((y / g_current_scale - g_offset.y) * g_get_slam_data.data.AGVMap.resolution - g_get_slam_data.data.AGVMap.physicsHeight - g_get_slam_data.data.AGVMap.originY);
        // g_robot_position.x = ( - g_get_slam_data.data.AGVMap.originX + g_get_slam_data.data.robotPose.x) / g_get_slam_data.data.AGVMap.resolution
        // g_robot_position.y = ( g_get_slam_data.data.AGVMap.physicsHeight + g_get_slam_data.data.AGVMap.originY - g_get_slam_data.data.robotPose.y ) / g_get_slam_data.data.AGVMap.resolution
        var url = `/on_reclocal?x=${temp_x}&y=${temp_y}&theta=${theta}`
        get_map_data(url);
        // console.log(temp_x);
        // console.log(temp_y);
        // console.log(g_current_scale);
    }


    // 主函数
    function main() {
        // 初始化先一次
        draw_slam_map();
        // 每隔一段时间询问一次，切换则可迅速进入界面
        setInterval(function () {
            // 图片位置
            draw_slam_map();
        }, 2000)

        // 载入时加载
        g_img.onload = function (event) {
            if (g_timer_id != null) {
                clearTimeout(g_timer_id)
                g_timer_id = null;
            }
            // 定时器
            g_timer_id = setTimeout(draw_slam_map, 200)
        }

        // 监听鼠标、键盘等事件
        listen_event();

        draw_image()
    }


    main();
</script>

</body>


</html>